package com.gagan.tplmatcher;

import com.gagan.tplmatcher.PatternTree.PatternData;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

/**
 * Extracts data from template.
 *
 *
 * @author gagan.goku@gmail.com
 */
public class PatternDetector {
  public static final List<String> patternFiles = new ArrayList<String>();
  public static final List<String> urls = new ArrayList<String>();

  public static final String BLINK_DIR =
      "/Users/gagansingh/Work/blinkMvn/src/main/resources/boutiques/";

  public static final List<String> PATTERN_FILE_LIST = new ArrayList<String>(Arrays.asList(
      "rat1.txt", "rat2.txt", "rat3.txt",
      "rat4.txt", "rat5.txt",
      "rat6.txt", "rat7.txt", "rat8.txt", "rat9.txt",
      "rat10.txt", "rat11.txt",
      "rat12.txt",
      "rat13.txt",
      "rat14.txt", "rat15.txt", "rat16.txt",
      "rat17.txt",
      "rat18.txt"
//      "rat19.txt"
//
//      "cnn0.txt", "cnn1.txt", "cnn2.txt", "cnn3.txt",
//      "cnn4.txt", "cnn5.txt", "cnn6.txt", "cnn7.txt",
//      "cnn8.txt", "cnn9.txt", "cnn10.txt","cnn11.txt",
//      "cnn12.txt"
  ));

  public static void main(String args[]) throws IOException {
    PatternDetector d = new PatternDetector();
    d.startMatching();
  }

  void startMatching() throws IOException {
    for (String patternFile : PATTERN_FILE_LIST) {
      patternFiles.add(BLINK_DIR + patternFile);
    }

    List<StringPattern> patterns = new ArrayList<StringPattern>();
    int idx = 0;
    for (String file : patternFiles) {
      String content = Util.readFile(file, false);
      content = content.replaceAll("\\{\\{", "").replaceAll("\\}\\}", "");
      patterns.add(new StringPattern(content, idx++));
    }

    urls.add("http://www.boutiques.com/lunr.py?q=1+madison&blink=1");
    String pageContent = Util.readFile(BLINK_DIR + "3.1_phillip_lim.html", true);
//    String pageContent = Util.readFile(BLINK_DIR + "1_madison.html", true);
//    String pageContent = Util.readFile(BLINK_DIR + "cnnblink.html", false);
//
    LinkedList<Object> list = new LinkedList<Object>();
    list.add(pageContent);

    int patternIdx = -1;
    for (StringPattern p : patterns) {
      patternIdx++;
      int j = 0;
      while (j < list.size()) {
        if (list.get(j) instanceof String) {
          String html = (String) list.get(j);
          List<List<MatchResult>> res = p.apply(html);

          if (!res.isEmpty()) {
            list.remove(j);
            res.add(new ArrayList<MatchResult>(Arrays.asList(new MatchResult(
                html.length(), html.length(), html, patternIdx))));
          } else {
            j++;
          }

          int startIdx = 0;
          for (List<MatchResult> l : res) {
            int begin = l.get(0).start;
            int end = l.get(0).end;
            String before = html.substring(startIdx, begin);
            startIdx = end;

            if (!before.isEmpty()) {
              list.add(j++, before);
            }
            if (l.size() != 1 || l.get(0).start != html.length() ||
                l.get(0).end != html.length()) {
              list.add(j++, l);
            } else {
//              System.out.println(l.toString());
            }
          }
        } else {
          j++;
        }
      }
    }

    StringBuilder remaining = new StringBuilder();
    for (Object o : list) {
      if (o instanceof String) {
        remaining.append(o);
        remaining.append("||");
      }
    }

    System.out.print(remaining.toString());

    List<String> allPatterns = new ArrayList<String>();
    for (StringPattern p : patterns) {
      allPatterns.add(p.getPattern());
    }
    List<Object> allData = new ArrayList<Object>();
    for (Object o : list) {
      if (o instanceof String) {
        allData.add(o);
      } else if (o instanceof List) {
        List<?> l = (List<?>) o;

        List<String> matches = new ArrayList<String>();
        for (int i = 1; i < l.size(); i++) {
          MatchResult res = (MatchResult) l.get(i);
          matches.add(res.data);
        }
        allData.add(new PatternData(((MatchResult) l.get(0)).patternIdx, matches));

        MatchResult fullMatch = (MatchResult) l.get(0);
        List<String> currentPattern = new ArrayList<String>(Arrays.asList(
            allPatterns.get(fullMatch.patternIdx)));

        PatternData patternData = new PatternData(0, matches);
        PatternTree j = new PatternTree(currentPattern, new ArrayList<Object>(
            Arrays.asList(patternData)));

        String stitched = PatternTree.stitchCompleteHtml(j);
        if (!fullMatch.data.equals(stitched)) {
          throw new RuntimeException("not equal");
        }
      } else {
        throw new RuntimeException("Unknow o:");
      }
    }

    PatternTree patternTree = new PatternTree(allPatterns, allData);
    String stitched = PatternTree.stitchCompleteHtml(patternTree);
    if (!pageContent.equals(stitched)) {
      throw new RuntimeException("not equal");
    }
    System.out.println("All OK");
  }

  private String getUrlContents(String url) {
    // fetch url contents.
    URLConnection conn;
    String pageContent = "";
    try {
      URL blink = new URL(urls.get(0));
      conn = blink.openConnection();

      BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
      String inputLine;

      while ((inputLine = in.readLine()) != null) {
        pageContent += inputLine + "\n";
      }
      in.close();
      return pageContent;
    } catch (MalformedURLException e) {
      throw new RuntimeException(e);
    }  catch (IOException e) {
      throw new RuntimeException(e);
    }
  }
}
